package control.elements;

import java.util.ArrayList;

import control.elements.gear.Gear;
import control.elements.helpers.ElementType;


/**
 * 
 * @author Scott Freeman
 *
 */
public class Caller{

	
	private static final int MAX_SMN_SKILL = 433;

	private static final int MIN_SMN_SKILL = 0;

	/**
	 * Level of this summoner.
	 */
	private int my_level;
	
	/**
	 * Name of this summoner.
	 */
	private String my_name;
	
	/**
	 * Summoning skill of this summoner.
	 */
	private int my_skill;
	
	/**
	 * Current Avatar of this summoner.
	 */
	private Avatar my_pet;
	
	/**
	 * Current max mp of this summoner.
	 */
	private int my_mp;
	
	/**
	 * 
	 */
	private int my_refresh;
	/**
	 * 
	 */
	private Gear[] gear_set;
	
	/**
	 * 
	 * @param the_name
	 * @param the_level
	 * @param the_mp
	 */
	public Caller(final String the_name, final int the_level, final int the_mp) 
		throws IllegalArgumentException{
		
		if(the_level > 99 || the_level < 1) {
			throw new IllegalArgumentException("Level out of Range.");
		}
		setMyName(the_name);
		setMyLvl(the_level);
		if(the_mp <= 9999 & the_mp >= 0) {
			my_mp = the_mp;
		} else {
			throw new IllegalArgumentException("Mp not valid.");
		}
		gear_set = new Gear[16];
		setDefaultGearList();
		
		
		if(my_level >= 90) {
			my_refresh = 2;
		} else {
			my_refresh = 1;
		}
	}
	
	public void setDefaultGearList() {
		ArrayList<Gear> gearlist = Gear.gearFactory("emptygearlist.txt");
		for(Gear g: gearlist ) {
				gear_set[g.getSlot()] = g;	
			}
	}

	/**
	 * 
	 */
	public int getMyRefresh(){
		return my_refresh;
	}
	
	/**
	 * @return the my_level
	 */
	public int getMyLvl() {
		return my_level;
	}

	/**
	 * @param myLevel the my_level to set
	 */
	private void setMyLvl(int myLevel) {
		my_level = myLevel;
	}

	/**
	 * @return the my_name
	 */
	public String getMyName() {
		return my_name;
	}

	/**
	 * @param myName the my_name to set
	 */
	private void setMyName(String myName) {
		my_name = myName;
	}

	/**
	 * @return the my_skill
	 */
	public int getMySkill() {
		
		return calcSkill();
	}

	/**
	 * @param mySkill the my_skill to set
	 */
	public void setMySkill(int mySkill) 
	throws IllegalArgumentException{
		if(mySkill <= MAX_SMN_SKILL && mySkill >= MIN_SMN_SKILL){
			my_skill = mySkill;
			
		} else {
			throw new IllegalArgumentException();
		}
		
	}

	/**
	 * @return the my_pet
	 */
	public Avatar getMyPet() {
		return my_pet;
	}
	
	public boolean hasPet() {
		boolean pet = true;
		if(my_pet == null) {
			pet = false;
		}
		return pet;
	}

	/**
	 * @param myPet the my_pet to set
	 */
	public void setMyPet(Avatar the_Pet) {
		my_pet = the_Pet;
	}

	/**
	 * @return the my_mp
	 */
	public int getMyMp() {
		return my_mp;
	}

	/**
	 * @param myMp the my_mp to set
	 */
	public void setMyMp(int myMp) {
		my_mp = myMp;
	}

	/**
	 * 
	 */
	public int calcRefresh(){
		int refresh = 0;
		for(int i = 0; i < gear_set.length; i++) {
			refresh = refresh + gear_set[i].getRefresh();
		}
		refresh = refresh + my_refresh;
		
		return refresh;
	}
	/**
	 * 
	 * @return
	 */
	private int calcSkill() {
		int skill = 0; 
		
		for(int i = 0; i < gear_set.length; i++) {
			skill = skill + gear_set[i].smn_skill();
			}
		skill = skill + my_skill;
		return skill;
	}
	/**
	 * 
	 * @param day The current day's element.
	 * @param w1 The current weather's element.
	 * @param w2 The auxilary weather's element.
	 * @return
	 */
	public int calculatePerp(final ElementType day,
			final ElementType w1, final ElementType w2) {
		int perp = my_pet.calculatePerp();
		for(int i = 0; i < gear_set.length; i++) {
			if(gear_set[i].getCondition().equals("All")) {
				perp = perp - gear_set[i].getPerp();
				
			}
		}
		
		if(gear_set[7].getName().equals("Caller's Bracers +1")) {
			if(my_pet.getElement().isSameAs(day)) {
				perp = perp / 2;
			}
		} else if(gear_set[7].getName().equals("Caller's Bracers +2")) {
			if(my_pet.getElement().isSameAs(w1) || my_pet.getElement().isSameAs(day)) {
				perp = perp / 2;
			}
		}
		//Conditional Perpetuation Reduction.
		for(int i = 0; i < gear_set.length; i++) {
			if(gear_set[i].getCondition().equals("Day") 
				&& day.isSameAs(my_pet.getElement())) {
				perp = perp - gear_set[i].getPerp();
				
			} else if(gear_set[i].getCondition().equals("Weather") 
				&& w1.isSameAs(my_pet.getElement())) {
				perp = perp - gear_set[i].getPerp();
				
			} else if(gear_set[i].getCondition().equals("Diabolos")
				&& my_pet.getName().equals("Diabolos")) {
				perp = perp - gear_set[i].getPerp();
				
			} else if(gear_set[i].getCondition().equals("Light Spirit")
				&& my_pet.getName().equals("Light Spirit")) {
				perp = perp - gear_set[i].getPerp();
				
			} else if(gear_set[i].getCondition().equals("Dark Spirit")
				&& my_pet.getName().equals("Dark Spirit")) {
				perp = perp - gear_set[i].getPerp();
				
			} else if(gear_set[i].getCondition().equals("Fenrir")
				&& my_pet.getName().equals("Fenrir")) {
				perp = perp - gear_set[i].getPerp();
			}
		}
		if(perp < 0) {
			perp = 0;
		}
		return perp;
	}
	
	
	/**
	 * 
	 * @param the_gear
	 * @return
	 */
	public boolean setGear(String the_gear) {
		boolean result = false;
		ArrayList<Gear> gearlist = Gear.gearFactory("summonergear.txt");
		for(Gear g: gearlist ) {
			if(the_gear.equals(g.getName())) {
				if(g.getLvl() <= my_level) {
					gear_set[g.getSlot()] = g;
					result = true;	
				}else {
					throw new IllegalArgumentException("Your level is too low to equip this.");
				}
				
			}
		}
		
		return result;
	}
	
	/**
	 * 
	 * @return
	 */
	public Gear[] getGear() {
		Gear[] temp = gear_set; 
		
		return temp;
	}
}
